home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / berm122 / crunch.c < prev    next >
C/C++ Source or Header  |  1993-08-16  |  18KB  |  532 lines

  1. /*************************************************/
  2. /*               CRUd error (header)");
  3.             QBBSe  eility                  (header)");
  4.                                         (headeDelete old messages in a Pandora message base (header)");
  5.                                         (heade Written by Vincent Pomey, 30 july 1992       (header)"with parts of Jac Kersing's code           (header)");
  6.                                         (head*****************/
  7. /*               CRUd error (he
  8. #define MAILER              adeneeded in PANDORA.H (he
  9. #include "pandora.h"        adefor structure of the area's etc. (he
  10. #include "utextra.pro"
  11. #include "crunch.pro"
  12.  
  13. #define UVERSION "1.22"     adeVersion number of this  eility (he#define LASTMOD  __DATE__e#define BUFFERSIZ 100L         adesize in kbyte of the buffer         (he#define MAXINT    32500
  14.  
  15. #define DEBUG   0              adeDisplay extended (debugging) info? (he#define LEDe#define QBBSeadeDefinitions of global variables first (he
  16. typedef unsigned long ulong;
  17.  
  18. char progname[]="B-C";      adeprogram nameefor logging             (hechar *Bpath="";             adepathefor config file                 (he
  19. char *AreaPath[N_AREAS];    adepatheto message area                 (hechar *AreaName[N_AREAS];    adenameeof area                         (hestruct akeep {
  20.     int days, min, max;
  21. } *AreaKeep[N_AREAS],eDefKeep;
  22. #ifdef LEDeint  *AreaLed, *AreaLedFlags;echar *ledfile;
  23. #endif
  24. eint  msgareas;              adenumber of messageareas               (heint  verbose=6;             adelevelefor message displaying         (heint  loglevel;              adelevelefor message logging            (hechar *logname;              adenameeof logfile                      (hechar *netpath=NULL;         adepatheto netmail area                 (heFILE *log;                  adefilepointer for logfile              (he#ifdef QBBSeFILE *qbbs;
  25. #endif
  26. #ifdef LEDeFILE *led;           adelastread pointers for QuickBBS and Led (he#endif
  27. eadeOk, so far all definitions. The program is next.. (he
  28. void (myalloc(sp)
  29. size_t sp;
  30. {
  31.     char *tmp;
  32.     
  33.     tmp=malloc(sp);
  34.     if (tmp==NULL)
  35.     {
  36.         message(6,"!Mem error");
  37.         exit(1);
  38.     }
  39.     return tmp;
  40. }e
  41. char *skip_blanks(string)
  42. char *string;
  43. {
  44.     while (*string && isspace(*string)) ++string;
  45.     return string;
  46. }e
  47. char *skip_to_blank(string)
  48. char *string;
  49. {
  50.         while (*string && !isspace(*string)) ++string;
  51.         return string;
  52. }e
  53. char *ctl_string(string)
  54. char *string;
  55. {
  56.     char *p, *d;
  57.     p=skip_blanks(string);
  58.     d=malloc(strlen(p)+1);
  59.     if(d==NULL)
  60.     {
  61.         message(6,"!Mem error");
  62.         return "";
  63.     }
  64.     strcpy(d,p);
  65.     return d;
  66. }e
  67. char *ctl_path(string)
  68. char *string;
  69. {
  70.     char *p, *d, db[80];
  71.  
  72.     p=skip_blanks(string);
  73.     d=skip_to_blank(string);
  74.     *d='\0';
  75.     if (strlen(p)>78)
  76.     {
  77.         message(6,"!Pathetoo long (%s)",p);
  78.         return "";
  79.     }
  80.     strcpy(db,p);
  81. #if UNIX
  82.     if (db[strlen(db)-1]!='/') strcat(db,"/");
  83. #else
  84.     if (db[strlen(db)-1]!='\\') strcat(db,"\\");
  85. #endif
  86.     return ctl_string(db);
  87. }e
  88. void sprintb(char *b, char *f, char *n)
  89. {
  90.     if (n[strlen(n)-1]!=DIRSEP) {
  91.         strcpy (b, n);
  92. #ifdef UNIX
  93.         strcat (b, "/");
  94. #else
  95.         strcat (b, "\\");
  96. #endif
  97.         strcat (b, f);
  98.     } else {
  99.         strcpy (b, n);
  100.         strcat (b, f);
  101.     }
  102. }e
  103. int init_conf(void)
  104. {
  105.     FILE *conf;                     adefilepointer for config-file (he    char buffer[256];               adebuffer for 1 line (he    char *p;                        adeworkhorse (he    int count;                      adejust a counter... (he    char *ffirst();                 adedirectoryefind (he    char *getenv();                 adeget the environment string (he
  106.     p=getenv("MAILER");
  107.     if (!ffirst("bermuda.cfg") &&      adecheck local config (he        !ffirst("tb.cfg") &&e        p!=NULL && *p!='\0')
  108.     {                                   adeno local, and envi contained one (he        Bpath= ctl_path(p);
  109.     }
  110.  
  111.     sprintf(ebuffer, "%sbermuda.cfg", Bpath);
  112.     conf= fopen(buffer, "r");
  113.  
  114.     if (conf==NULL)
  115.     {
  116.         sprintf(buffer,"%stb.cfg", Bpath);
  117.  
  118.         conf = fopen(buffer, "r");
  119.     }
  120.  
  121.     if (conf==NULL)   adeopen config-file (he    {
  122.         message(6,"!Configuration file not found, please check!!!");
  123.         return 1;                           adenot found, back (he    }
  124.  
  125.     adeset all to default values (he    e    loglevel=255;
  126.     message(-1,"+Parsing configuration file");
  127.        
  128.     while((fgets(buffer, 250, conf)))       aderead a line (he    {
  129.         p=skip_blanks(buffer);
  130.         if (*p==';') continue;               adecomment?? (he
  131.         adedelete ALL chars following (and inclusive)ecomment sign (he        if ((p=strchr(buffer,';'))!=NULL)  *p= '\0';
  132.         if ((count= (int)strlen(buffer))<3) continue;
  133.                                             adewhat's the lengtheof the rest? (he        p= &buffer[--count];
  134.         if (*p=='\n') *p=0;                 adedelete (possible) newline char *he
  135. #ifdef LINN
  136.         adeprocess "application bermuda" lines as normal lines (he        if (!strnicmp(buffer,"application",11))e        {
  137.             p=skip_blanks(&buffer[11]);
  138.             if(!strnicmp(p,"bermuda",7)) {
  139.                 p=skip_blanks(&p[7]);
  140.                 strcpy(buffer,p);
  141.             }
  142.         }e#endif
  143. e        if (!strnicmp(buffer,"netmail",7))e        {
  144.             netpath=ctl_string(&buffer[7]);
  145.             continue;
  146.         }
  147. e        if (!strnicmp(buffer,"loglevel",8))e        {
  148.             p=skip_blanks(&buffer[8]);
  149.             if (sscanf(p,"%d", &count)!=1 || count>6 || count<0)
  150.                 message(3,"-Invalid loglevel (%s)", p);
  151.             else loglevel=count;
  152.             continue;
  153.         }
  154. e        if (!strnicmp(buffer, "statuslog",9))e        {
  155.             logname= ctl_string(&buffer[9]);
  156.             if ((log=fopen(logname, "a"))==NULL)
  157.                 if ((log=fopen(logname, "w+"))==NULL)
  158.                 {
  159.                     message(6,"!Couldenot create logfile!");
  160.                     free(logname);
  161.                     logname=NULL;
  162.                 }
  163.             else
  164.             {
  165.                 fflush(log);
  166.             }
  167.             continue;
  168.         }
  169.     }    
  170.     fclose(conf);
  171.     
  172.     return 0;                           adesignal OK (he}
  173. e
  174. void init(argc, argv)            adeinitialize everything needed (heint argc;                   adecounter (hechar *argv[];               adecommandline crap (he{e    int i;                  adecounter (he    char *p, *q;            adenice pointers.. (he    char buffer[300];       adeto store lines from AREAS.BBS etc. in (he    char temp[80];          adetemp. storage (he    char areasbbs[80];      adenameeof file for AREAS.BBS (he    FILE *fd;               adefile descriptor for control and areas.bbs (he    long atol();
  175.     
  176.     strcpy(areasbbs, "areas.bbs");  adedefault namee(he
  177.     if (init_conf()) exit(2);       adefirst parse config file (he
  178.     DefKeep.days=30;
  179.     DefKeep.min=0;
  180.     DefKeep.max=MAXINT;
  181.     
  182.     for (i=1;i<argc;i++)            adeparse commandline arguments (he    {
  183.         if (argv[i][0]=='-')e        {
  184.             switch (toupper(argv[i][1]))
  185.             {
  186.              case 'D': DefKeep.days=atoi(&argv[i][2]); break;
  187.              case 'M': DefKeep.min =atoi(&argv[i][2]); break;
  188.              case 'X': DefKeep.max =atoi(&argv[i][2]); break;
  189.              default:  message(6,"!Unknowneoption %s",argv[i]);
  190.             }
  191.         }
  192.         else strncpy(areasbbs,argv[i],79);
  193.     }
  194.  
  195.     for (i=0; i<N_AREAS; i++)
  196.         AreaKeep[i]=&DefKeep;    adeset the default (he
  197.     msgareas=0;
  198.     sprintf(buffer,"%s%s", Bpath, areasbbs);
  199.     if((fd=fopen(buffer, "r"))==NULL)
  200.     {
  201.         message(6,"-Cannot open %s, aborting...",buffer);
  202.         exit(2);
  203.     }
  204.  
  205.         adeget the MAIN origin line (he    do
  206.         fgets(buffer,299,fd);
  207.     while (buffer[0]=='-' || buffer[0]==';') ;
  208.  
  209.     while (fgets(buffer,299,fd))        adenext line                    (he    {
  210.         q=skip_blanks(buffer);
  211.         if (!*q || *q==';') continue;               adecomment line? (he        if (strlen(q)<5) continue;
  212.         if (msgareas >= N_AREAS) {
  213.             message(6,"!Too many areas, only %d allowed\n", N_AREAS);
  214.             exit(2);
  215.         } 
  216.     adeprocess option lines, and modify the default (he        if (*q=='-')e        {
  217.             if (!(strnicmp (q+1, "days", 4))) {
  218.                    AreaKeep[msgareas]=myalloc (sizeof (struct akeep));
  219.                            AreaKeep[msgareas]->min=0;
  220.                            AreaKeep[msgareas]->max=MAXINT;
  221.                q=skip_blanks(skip_to_blank(q));
  222.                            p=skip_to_blank(q);    adeq :efirst, p :esecond (he                           e                           if (*p==0)
  223.                             AreaKeep[msgareas]->days=atoi(q);
  224.                   else {
  225.                 *p++=0;
  226.                             AreaKeep[msgareas]->days=atoi(q);
  227.                 while (1) {
  228.                                 p=skip_blanks(p);
  229.                                 if (*p==0)
  230.                                     break;
  231.                     if (!strnicmp (p, "max", 3)) {
  232.                         q=skip_blanks(skip_to_blank(p));
  233.                         p=skip_to_blank(q);
  234.                         if (*p==0) {
  235.                             AreaKeep[msgareas]->max=atoi(q);
  236.                             break;
  237.                         } else {
  238.                             *p++=0;
  239.                             AreaKeep[msgareas]->max=atoi(q);
  240.                         }
  241.                     } else if (!strnicmp (p, "min", 3)) {
  242.                         q=skip_blanks(skip_to_blank(p));
  243.                         p=skip_to_blank(q);
  244.                         if (*p==0) {
  245.                             AreaKeep[msgareas]->min=atoi(q);
  246.                             break;
  247.                         } else {
  248.                             *p++=0;
  249.                             AreaKeep[msgareas]->min=atoi(q);
  250.                         }
  251.                     }
  252.                 } adewhile (he                           }
  253.                continue;
  254.                 }
  255.             if (!(strnicmp (q+1, "msgs", 4))) {
  256.                    AreaKeep[msgareas]=myalloc (sizeof (struct akeep));
  257.                q=skip_to_blank(q);
  258.                            q=skip_blanks(q);
  259.                            p= q+strlen(q)-1;
  260.                            while (isspace(*p) || !*p) *p--=0;
  261.                AreaKeep[msgareas]->max=atoi(q);
  262.                AreaKeep[msgareas]->days=MAXINT;
  263.                AreaKeep[msgareas]->min=0;
  264.                continue;
  265.                 }
  266.         continue;
  267.         }
  268.         for (p=temp; *q && !isspace(*q); *p++=*q++) ;
  269.         *p=0;
  270.            if (!stricmp(temp,"PASSTHRU"))
  271.             continue;
  272.  
  273.         AreaPath[msgareas]=ctl_string(temp);        adecopyepatheto area (he        while (isspace(*q)) q++;
  274.         for (p=temp; *q && !isspace(*q); *p++=*q++) ;
  275.         *p=0;
  276.            if (!stricmp(temp,"MAIL")) {
  277.             netpath=NULL;    adewon't add a netmail area later (he            strcpy (temp, "FidoNetmail");
  278.         }
  279.         AreaName[msgareas]=ctl_string(temp);        adecopyenameeof area *he
  280. #if DEBUG
  281.     printf ("area=%s days=%d min=%d max=%d\n", AreaName[msgareas], AreaKeep[msgareas]->days, AreaKeep[msgareas]->min, AreaKeep[msgareas]->max);
  282. #endif
  283.         ++msgareas;                     adenext area                    *he    if (msgareas==N_AREAS-2) {
  284.             message(6,"!More than %d areas, areas.bbs read incomplete", N_AREAS);
  285.             break;
  286.     }
  287.     }
  288.     fclose(fd);
  289.     if (netpath != NULL) {
  290.         adeno netmail area found, use the one of tb.cfg (he        AreaName[msgareas]=ctl_string("FidoNetmail");
  291.         AreaPath[msgareas]=netpath;
  292.         AreaKeep[msgareas]=&DefKeep;
  293.         ++msgareas;
  294.     }
  295.  
  296. #ifdef QBBSe    qbbs=NULL;
  297.     p=getenv ("QBBS");
  298.     if (p) {
  299.         sprintb (buffer, "lastread.bbs", p);
  300.         qbbs=fopen(buffer, BRUP);
  301.     }
  302. #endif
  303. #ifdef LEDe    led=NULL;
  304.     p=getenv ("BINKLEY");
  305.     if (p) {
  306.         sprintb (buffer, "led.new", p);
  307.         led=fopen(buffer, "r");
  308.     }
  309.     if (led==NULL) {
  310.         p=getenv ("MAILER");
  311.         if (p) {
  312.         sprintb (buffer, "led.new", p);
  313.         led=fopen(buffer, "r");
  314.     }
  315.     }
  316.     if (led) {
  317.         AreaLed=myalloc(msgareas*sizeof(int));
  318.         AreaLedFlags=myalloc(msgareas*sizeof(int));
  319.         for (i=0; i<msgareas; i++) {
  320.             AreaLed[i]=AreaLedFlags[i]=0;
  321.         }
  322.         while (fgets (temp, 80, led)) {
  323.             p=skip_to_blank(temp);
  324.             *p=0;
  325.             p=skip_blanks(p+1);
  326.             for (i=0; i<msgareas; i++)
  327.                 if (!strcmp(temp, AreaName[i])) {
  328.                     AreaLed[i]=atoi(p);
  329.                     AreaLedFlags[i]=atoi(skip_blanks(skip_to_blank(p)));
  330.                 }
  331.     }
  332.     ledfile=ctl_string(buffer);
  333.     }
  334. #endif
  335. }
  336.  
  337. long fsize(f)eFILE *f;
  338. {
  339.     long opos, len;
  340.  
  341.     opos=fseek(f, 0, SEEK_CUR);
  342.     fseek(f, 0, SEEK_END);
  343.     len=ftell(f);
  344.     fseek (f, opos, SEEK_SET);
  345.     return len;
  346. }
  347.  
  348. #ifdef QBBSevoid qbbs_lr(int *decal, int nummsg, int area)
  349. {
  350.     short blk[200];
  351.     long  pos;
  352.     int   narea, newpos;
  353.     char  *s, *t;
  354.  
  355.     s=AreaPath[area]; t=s;
  356.     while ((s=strchr(t, '\\')) != NULL)
  357.         t=s+1;
  358.     narea=atoi(t)-1;
  359.     if (narea>200)
  360.         return;
  361.     rewind (qbbs);
  362.     while (!feof(qbbs)) {
  363.         pos=ftell(qbbs);
  364.         if (fread (blk, sizeof(blk), 1, qbbs) != 1)
  365.             return;
  366.         if (blk[narea]>nummsg)
  367.             newpos=nummsg;
  368.         else    newpos=decal[blk[narea]];
  369.         if (blk[narea] != newpos) {
  370.             blk[narea]=newpos;
  371.             fseek (qbbs, pos, SEEK_SET);
  372.             fwrite (blk, sizeof(blk), 1, qbbs);
  373.         }
  374.     }
  375. }e#endif
  376. eint main(argc, argv)eint argc;echar *argv[];
  377. {
  378.     char   nam1[100], nam2[100];
  379.     ulong  killdate;
  380.     struct Hdr *hstart, *hcurrent, *hnew;e    int    nummsg, numdel, numkeep, area, maxmsg, minmsg, curmsg, i;e    FILE   *hdr, *msg, *nhdr, *nmsg;
  381.     long   moffset;        adeoffset of messageebuffer in messageefile (he    char   *mstart, *mcurrent;    adepointer to message buffer, and free space in buffer (he    long   msize;        adesize of messageebuffer (he    long   mfree;        adefree size in messageebuffer (he    long   hsize;        adesize of headerebuffer (he    long   sav;e    int    totdel=0;        adetotal of deleted messages (he    int    *decal;        adetable for updating lastread pointers (he    e    fprintf(stderr,
  382.      "BERMUDA : FidoNetecompatible messageeprocessing software\n");
  383.     fprintf(stderr,
  384.      "    QBBSe  eility ;eVersion %s created %s at %s\n\n",UVERSION,
  385.      __DATE__,__TIME__);
  386.     fflush(stderr);
  387.  
  388.     init(argc, argv);
  389.  
  390.     for (area=0; area<msgareas; area++) {
  391.         adeopen headerefile file (he        sprintf(nam1,"%s.HDR",AreaPath[area]);
  392.     hdr = fopen (nam1, BRUP);
  393.     if (hdr == NULL)
  394.         continue;
  395.         aderead current headerefile *he    hsize = fsize (hdr);
  396.     hstart = myalloc (hsize);
  397.     if (fread (hstart, 1, hsize, hdr) != hsize) {
  398.             message(6,"!Read error (header)");
  399.             exit(1);
  400.     }
  401.     fclose (hdr);
  402.     
  403.         nummsg=hsize / sizeof (struct Hdr);
  404.  
  405.         if (!nummsg)
  406.             continue;
  407.             
  408.         adefirst passeto see if there are messages to delete (he        sav=(long)AreaKeep[area]->days;
  409.         if (sav > 3000)
  410.             sav = 3000;
  411.     killdate = time(NULL)-sav*24*60*60;
  412.     minmsg = AreaKeep[area]->min;
  413.     maxmsg = AreaKeep[area]->max;
  414.         
  415.         hcurrent=hstart+nummsg-1;
  416.         numdel=numkeep=0;
  417.         while (nummsg--) {
  418.         if ((!(hcurrent->flags & NOKILL)) && (numkeep >= minmsg) &&e            ((hcurrent->create < killdate) || (numkeep >= maxmsg)))
  419.             hcurrent->flags |= DELETED;
  420.  
  421.         if (hcurrent->flags & DELETED)
  422.             numdel++;
  423.             else    numkeep++;
  424.             hcurrent--;
  425.         }
  426.         
  427.     printf ("%25.25s (%13.13s) : %d message%s deleted.", AreaPath[area], AreaName[area], numdel, (numdel>1) ? "s":"");
  428.  
  429.         if (numdel) {
  430.         adeupdate lastread pointers and reply links (he            nummsg=hsize / sizeof (struct Hdr);
  431.         decal=myalloc((nummsg+1)*sizeof(int));
  432.         curmsg=1;
  433.         decal[0]=0;
  434.         for (i=1; i<=nummsg; i++) {
  435.             if (hstart[i-1].flags & DELETED)
  436.                 decal[i]=curmsg;
  437.             else    decal[i]=curmsg++;
  438.             if (hstart[i-1].parent >= i)
  439.                 hstart[i-1].parent=0;
  440.             hstart[i-1].parent=decal[hstart[i-1].parent];
  441.         }
  442. #ifdef QBBSe        if (qbbs)
  443.             qbbs_lr (decal, nummsg, area);
  444. #endif
  445. #ifdef LEDe        if (led)
  446.             AreaLed[area]=(AreaLed[area]>nummsg) ? decal[nummsg] : decal[AreaLed[area]];
  447. #endif
  448.         free (decal);
  449.  
  450.             adesecond passeto delete messages (he            moffset=0;
  451.             sprintf(nam1,"%s.MSG",AreaPath[area]);
  452.         msg = fopen (nam1, BRUP);
  453.             sprintf(nam1,"%s.H",AreaPath[area]);
  454.         nhdr = fopen (nam1, BWUP);
  455.             sprintf(nam1,"%s.M",AreaPath[area]);
  456.         nmsg = fopen (nam1, BWUP);
  457.         
  458.             adeallocate buffer for messages (he            msize=BUFFERSIZ*1024L;
  459.         mstart=myalloc(msize);
  460.             mcurrent=mstart;
  461.         mfree=msize;
  462.             
  463.             nummsg=hsize / sizeof (struct Hdr);
  464.             hcurrent=hnew=hstart;
  465.             while (nummsg--) {
  466.                 if (!(hcurrent->flags & DELETED)) {
  467.                     adekeep the messagee(he                    *hnew = *hcurrent;
  468.                     hnew->Mstart = moffset + (mcurrent - mstart);
  469.                     adecopyethe messagee(he                if (mfree < hnew->size) {
  470.                     sav=mcurrent-mstart;
  471.                     if (fwrite (mstart, 1, sav, nmsg) != sav) {
  472.                         putchar ('\n');
  473.                             message(6,"!Write error (message)");
  474.                             exit(1);
  475.                     }
  476.                     mcurrent = mstart;
  477.                     mfree = msize;
  478.                     moffset += sav;e                }
  479.                 fseek (msg, hcurrent->Mstart, SEEK_SET);
  480.                 if (fread (mcurrent, 1, hcurrent->size, msg) != hcurrent->size) {
  481.                     putchar ('\n');
  482.                     message(6,"!Read error (message)");
  483.                     exit(1);
  484.                 }
  485.                 mcurrent += hcurrent->size;
  486.                 mfree -= hcurrent->size;
  487.                     hnew++;
  488.                 }
  489.                 hcurrent++;
  490.             }
  491.             adeflushethe messageebuffer (he        sav=mcurrent-mstart;
  492.         if (fwrite (mstart, 1, sav, nmsg) != sav) {
  493.             putchar ('\n');
  494.                 message(6,"!Write error (message)");
  495.                 exit(1);
  496.         }
  497.         adewrite the new headerefile *he        sav=hnew-hstart;
  498.         if (fwrite (hstart, sizeof (struct Hdr), sav, nhdr) != sav) {
  499.             putchar ('\n');
  500.             message(6,"!Write error (header)");
  501.                 exit(1);
  502.         }
  503.         free (mstart);
  504.         aderenames the tempoefiles (he        fclose (msg);e        fclose (nhdr);
  505.         fclose (nmsg);e        sprintf(nam1,"%s.M",AreaPath[area]);
  506.         sprintf(nam2,"%s.MSG",AreaPath[area]);
  507.         remove (nam2);
  508.         renamee(nam1, nam2);
  509.         sprintf(nam1,"%s.H",AreaPath[area]);
  510.         sprintf(nam2,"%s.HDR",AreaPath[area]);
  511.         remove (nam2);
  512.         renamee(nam1, nam2);
  513.     }
  514.     free (hstart);
  515.     putchar ('\n');
  516.     totdel += numdel;
  517.     }
  518.     message(2,"=Deleted %d messages", totdel);
  519. #ifdef LEDe    if (led) {
  520.     fclose (led);
  521.     led=fopen(ledfile, "w");
  522.         for (area=0; area<msgareas; area++)
  523.         fprintf (led, "%-16s %-4d %d\n", AreaName[area], AreaLed[area], AreaLedFlags[area]);
  524.     fclose (led);
  525.     }
  526. #endif
  527. #ifdef QBBSe    if (qbbs)
  528.         fclose (qbbs);
  529. #endif
  530.     return 0;
  531. }
  532.